package eu.fishcode.android.ui;

import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;

import eu.fishcode.android.ui.component.Panel;
import eu.fishcode.android.ui.component.ToolBar;
import eu.fishcode.android.utils.BootAnimationZip;
import eu.fishcode.android.utils.Configuration;
import eu.fishcode.android.utils.ImageFileFilter;
import eu.fishcode.android.utils.Utils;

public class EditToolBar extends ToolBar implements FocusListener {

	private static final long serialVersionUID = 1111111100000000112L;

	private ArrayList<String[]> listDesc;
	private Panel panelPart;
	private Panel panelRes;
	private Panel panelFrame;
	private Panel panelVideo;
	private JComboBox partList;
	private JFormattedTextField textCicle;
	private JFormattedTextField textFps;
	private JFormattedTextField textFrame;
	private JFormattedTextField textHeight;
	private JFormattedTextField textPause;
	private JFormattedTextField textWidth;

	public EditToolBar(ActionListener ai) {
		super("Bootanimation properties", ai, SwingConstants.VERTICAL);
	}

	public EditToolBar(String name, ActionListener ai, int orientation) {
		super(name, ai, orientation);
	}

	@Override
	protected void addButtons() {
		super.addButtons();
		JButton button = null;
		TitledBorder title;
		title = BorderFactory.createTitledBorder(Utils
				.getLabel("toolbar.resolution"));
		this.panelRes = new Panel();
		this.panelRes.setBorder(title);
		this.panelRes.setPreferredSize(new Dimension(220, 80));
		this.textWidth = new JFormattedTextField();
		this.textWidth.setPreferredSize(new Dimension(40, 24));
		this.textWidth.setValue(new Integer(0));
		this.textWidth.addFocusListener(this);
		this.panelRes.add(this.textWidth);
		this.panelRes.add(new JLabel("X"));
		this.textHeight = new JFormattedTextField();
		this.textHeight.setPreferredSize(new Dimension(40, 24));
		this.textHeight.setValue(new Integer(0));
		this.textHeight.addFocusListener(this);
		this.panelRes.add(this.textHeight);
		this.panelRes.add(new JLabel("FPS"));
		this.textFps = new JFormattedTextField();
		this.textFps.setPreferredSize(new Dimension(30, 24));
		this.textFps.setValue(new Integer(0));
		this.textFps.addFocusListener(this);
		this.panelRes.add(this.textFps);

		title = BorderFactory
				.createTitledBorder(Utils.getLabel("toolbar.part"));
		this.panelPart = new Panel();
		this.panelPart.setBorder(title);
		this.panelPart.setPreferredSize(new Dimension(220, 160));
		this.partList = new JComboBox();
		this.partList.addActionListener(this.actionListener);
		this.partList.setActionCommand("part.change");
		this.partList.setPreferredSize(new Dimension(120, 24));
		this.panelPart.add(this.partList);
		button = this.addButton("add.png", "part.add", this.panelPart);
		button.setPreferredSize(new Dimension(24, 24));
		button.setText("");

		button = this.addButton("remove.png", "part.remove", this.panelPart);
		button.setPreferredSize(new Dimension(24, 24));
		button.setText("");

		final JPanel panelPartGrid = new JPanel();
		// panelPartGrid.setOpaque(true);
		panelPartGrid.setBackground(new Color(0xcf, 0xde, 0xf0, 0));
		panelPartGrid.setLayout(new GridLayout(3, 3));
		panelPartGrid.add(new JLabel(Utils.getLabel("toolbar.part.pause")));
		this.textPause = new JFormattedTextField();
		this.textPause.setPreferredSize(new Dimension(30, 24));
		this.textPause.setValue(new Integer(0));
		this.textPause.addFocusListener(this);
		panelPartGrid.add(this.textPause);
		panelPartGrid
				.add(new JLabel(Utils.getLabel("toolbar.part.pause.desc")));
		panelPartGrid.add(new JLabel(Utils.getLabel("toolbar.part.cicle")));
		this.textCicle = new JFormattedTextField();
		this.textCicle.setPreferredSize(new Dimension(30, 24));
		this.textCicle.setValue(new Integer(0));
		this.textCicle.addFocusListener(this);
		panelPartGrid.add(this.textCicle);
		panelPartGrid
				.add(new JLabel(Utils.getLabel("toolbar.part.cicle.desc")));
		panelPartGrid.add(new JLabel(Utils.getLabel("toolbar.part.frame")));
		this.textFrame = new JFormattedTextField();
		this.textFrame.setPreferredSize(new Dimension(30, 24));
		this.textFrame.setEditable(false);
		this.textFrame.setValue(new Integer(0));
		panelPartGrid.add(this.textFrame);
		panelPartGrid
				.add(new JLabel(Utils.getLabel("toolbar.part.frame.desc")));
		this.panelPart.add(panelPartGrid);

		this.add(this.panelRes);
		this.add(this.panelPart);

		title = BorderFactory.createTitledBorder(Utils
				.getLabel("toolbar.frame"));
		this.panelFrame = new Panel();
		this.panelFrame.setBorder(title);
		this.panelFrame.setPreferredSize(new Dimension(220, 160));
		this.panelFrame.setLayout(new GridLayout(3, 2));
		this.addButton("prev.png", "frame.prev", this.panelFrame);

		this.addButton("next.png", "frame.next", this.panelFrame);

		this.addButton("list-add.png", "frame.add", this.panelFrame);

		this.addButton("list-remove.png", "frame.remove", this.panelFrame);

		this.addButton("video.png", "frame.import", this.panelFrame);

		this.addButton("edit.png", "frame.edit", this.panelFrame);

		this.add(this.panelFrame);
		title = BorderFactory.createTitledBorder(Utils
				.getLabel("toolbar.video"));
		this.panelVideo = new Panel();
		this.panelVideo.setBorder(title);
		this.panelVideo.setPreferredSize(new Dimension(220, 80));
		this.panelVideo.setLayout(new GridLayout(1, 2));
		this.addButton("start.png", "video.start", this.panelVideo);

		this.addButton("stop.png", "video.stop", this.panelVideo);

		this.add(this.panelVideo);
	}

	public void addFrame(String fileName) {
		try {

			final File file = new File(Utils.WorkPath + Utils.FileSeparator
					+ this.partList.getSelectedItem() + Utils.FileSeparator
					+ fileName);

			final int width = (Integer) this.textWidth.getValue();
			final int height = (Integer) this.textHeight.getValue();
			if ((width > 0) && (height > 0)) {
				final BufferedImage bi = new BufferedImage(width, height,
						BufferedImage.TYPE_INT_ARGB_PRE);

				final Graphics2D ig2 = bi.createGraphics();

				final Font font = new Font("TimesRoman", Font.BOLD, 20);
				ig2.setFont(font);
				final String message = "www.java2s.com!";
				final FontMetrics fontMetrics = ig2.getFontMetrics();
				final int stringWidth = fontMetrics.stringWidth(message);
				final int stringHeight = fontMetrics.getAscent();
				ig2.setPaint(Color.black);
				ig2.drawString(message, (width - stringWidth) / 2, (height / 2)
						+ (stringHeight / 4));

				ImageIO.write(bi, "PNG", file);
			} else {
				JOptionPane.showMessageDialog(null,
						Utils.getLabel("toolbar.frame.add.error.b"),
						Utils.getLabel("toolbar.frame.add"),
						JOptionPane.INFORMATION_MESSAGE);
			}

		} catch (final IOException e) {
			Utils.logger.log(Level.SEVERE, "edit file failed " + fileName, e);
		}
	}

	public void addPart() {
		final String partNew = JOptionPane.showInputDialog(null,
				Utils.getLabel("toolbar.part.add.message"),
				Utils.getLabel("toolbar.part.add"),
				JOptionPane.QUESTION_MESSAGE);
		if (partNew != null) {
			final File partDir = new File(Utils.WorkPath + Utils.FileSeparator
					+ partNew);
			if (!partDir.exists()) {
				partDir.mkdir();
				if (this.listDesc.size() == 1) {
					this.listDesc.add(new String[] { "p", "0", "0", partNew });
					this.loadDesc(this.listDesc);
				} else {
					final ArrayList<String[]> newListDesc = new ArrayList<String[]>();
					for (final String[] info : this.listDesc) {
						newListDesc.add(info);
						if ((info.length == 4)
								&& info[3].equals(this.partList
										.getSelectedItem())) {
							newListDesc.add(new String[] { "p", "0", "0",
									partNew });
						}
					}
					this.loadDesc(newListDesc);
				}
				BootAnimationZip.setDescription(Utils.WorkDescPath,
						this.listDesc);
			} else {
				JOptionPane.showMessageDialog(null,
						Utils.getLabel("toolbar.part.add.error"),
						Utils.getLabel("toolbar.part.add"),
						JOptionPane.WARNING_MESSAGE);
			}
		}
	}

	public void editFrame(File file) {
		try {
			if (Configuration.getString("settings.path.editor").equals(
					"Default")
					&& Desktop.isDesktopSupported()) {
				final Desktop desktop = Desktop.getDesktop();
				if (desktop.isSupported(Desktop.Action.EDIT)) {
					desktop.edit(file);
				} else if (desktop.isSupported(Desktop.Action.OPEN)) {
					desktop.open(file);
				}
			} else {
				final String[] strCommand = {
						Configuration.getString("settings.path.editor"),
						file.getAbsolutePath() };
				Runtime.getRuntime().exec(strCommand);
			}
		} catch (final IOException e) {
			Utils.logger.log(Level.SEVERE,
					"edit file failed " + file.getName(), e);
		}
	}

	@Override
	public void focusGained(FocusEvent e) {
	}

	@Override
	public void focusLost(FocusEvent e) {

		final ArrayList<String[]> newListDesc = new ArrayList<String[]>();
		for (final String[] info : this.listDesc) {
			if ((info.length == 4)
					&& info[3].equals(this.partList.getSelectedItem())) {
				newListDesc.add(new String[] { "p", this.textCicle.getText(),
						this.textPause.getText(), info[3] });
			} else if (info.length == 4) {
				newListDesc.add(info);
			} else if (info.length == 3) {
				newListDesc.add(new String[] { this.textWidth.getText(),
						this.textHeight.getText(), this.textFps.getText() });

			}
		}

		final Integer fps = (Integer) this.textFps.getValue();
		final int time = (int) ((1 / fps.doubleValue()) * 1000);

		EditToolBar.this.actionListener.actionPerformed(new ActionEvent(fps,
				time, "fps"));
		this.listDesc = newListDesc;
		BootAnimationZip.setDescription(Utils.WorkDescPath, newListDesc);
	}

	public String getPart() {
		return (String) this.partList.getSelectedItem();
	}

	public File[] getPartFile() {
		File[] filePart = new File[0];
		final File partDir = new File(Utils.WorkPath + Utils.FileSeparator
				+ this.partList.getSelectedItem());
		if (partDir.exists()) {
			filePart = partDir.listFiles(new ImageFileFilter());
			this.textFrame.setText(String.valueOf(filePart.length));
			for (final String[] info : this.listDesc) {
				if ((info.length == 4)
						&& info[3].equals(this.partList.getSelectedItem())) {
					this.textCicle.setText(info[1]);
					this.textPause.setText(info[2]);
				}
			}

			filePart = Utils.renameFile(filePart);
		}
		this.panelPart.validate();
		this.panelPart.repaint();
		return filePart;
	}

	public void loadDesc(ArrayList<String[]> desc) {
		this.listDesc = desc;
		this.partList.removeAllItems();

		for (final String[] info : desc) {
			if (info.length == 4) {
				this.partList.addItem(info[3]);
			} else {
				this.textWidth.setText(info[0]);
				this.textHeight.setText(info[1]);
				this.textFps.setText(info[2]);
			}
		}
		this.panelPart.validate();
		this.panelPart.repaint();
	}

	public void removeFrame(File file) {
		final int confirm = JOptionPane
				.showConfirmDialog(
						null,
						Utils.getLabel("toolbar.frame.remove.message")
								+ file.getName(),
						Utils.getLabel("toolbar.frame.remove"),
						JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
		if (confirm == JOptionPane.YES_OPTION) {

			if (file.exists()) {
				file.delete();
			}

		}

	}

	public void removePart() {
		final int confirm = JOptionPane.showConfirmDialog(
				null,
				Utils.getLabel("toolbar.part.remove.message")
						+ this.partList.getSelectedItem(),
				Utils.getLabel("toolbar.part.remove"),
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
		if (confirm == JOptionPane.YES_OPTION) {
			final File partDir = new File(Utils.WorkPath + Utils.FileSeparator
					+ this.partList.getSelectedItem());
			if (partDir.exists()) {
				partDir.delete();
			}
			final ArrayList<String[]> newListDesc = new ArrayList<String[]>();
			for (final String[] info : this.listDesc) {
				if ((info.length == 4)
						&& info[3].equals(this.partList.getSelectedItem())) {
					continue;
				}
				newListDesc.add(info);
			}
			this.loadDesc(newListDesc);
			BootAnimationZip.setDescription(Utils.WorkDescPath, this.listDesc);
		}
	}

}
